package com.li.java2;

import org.junit.Test;

import java.io.PrintStream;
import java.util.Comparator;
import java.util.Map;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 方法引用的使用
 * 场景：当要传递给Lambda体的操作，已经有了实现的方法，可以使用方法引用
 * 格式：类（或对象）：：方法名
 * 具体分为三种：
 * 对象：：非静态
 * 类：：静态方法
 * 类：：非静态
 *
 * 方法引用使用的要求：要求接口中的抽象方法的形参列表和返回值类型与方法引用方法的形参列表和返回值类型相同！
 */
public class MethodRefTest {

	// 情况一：对象 :: 实例方法
	//Consumer中的void accept(T t)
	//PrintStream中的void println(T t)
	@Test
	public void test1() {
		Consumer<String> con1 = str -> System.out.println(str);
		con1.accept("lambda");
		System.out.println("-------------------");

		PrintStream ps = System.out;
		Consumer<String> con2 = ps :: println;
		con2.accept("方法引用");
	}
	
	//Supplier中的T get()
	//Employee中的String getName()
	@Test
	public void test2() {
		Employee emp = new Employee(1001, "tom", 23, 444445);
		Supplier<String> sup1 = () ->emp.getName();
		System.out.println(sup1.get());
		System.out.println("------------------");
		Supplier<String> sup2 = emp :: getName;
		System.out.println(sup2.get());

	}

	// 情况二：类 :: 静态方法
	//Comparator中的int compare(T t1,T t2)
	//Integer中的int compare(T t1,T t2)
	@Test
	public void test3() {
		Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2);
		System.out.println(com1.compare(12, 21));

		System.out.println("***************");
		Comparator<Integer> com2  = Integer::compare;
		System.out.println(com2.compare(21, 12));
	}
	
	//Function中的R apply(T t)
	//Math中的Long round(Double d)
	@Test
	public void test4() {
		Function<Double , Long> func = new Function<Double, Long>() {
			@Override
			public Long apply(Double d) {
				return Math.round(d);
			}
		};

		Function<Double , Long> func1 = d -> Math.round(d);
		System.out.println(func1.apply(12.3));

		Function<Double,Long> funct2 = Math::round;
		System.out.println(funct2.apply(12.3));

	}

	// 情况三：类 :: 实例方法  (难点）
	// Comparator中的int comapre(T t1,T t2)
	// String中的int t1.compareTo(t2)
	@Test
	public void test5() {
		Comparator<Integer> com1 = (t1,t2) -> t1.compareTo(t2);
		System.out.println(com1.compare(12, 21));
		System.out.println("*****************");
		Comparator<Integer> com2 = Integer::compareTo;
		System.out.println(com2.compare(21, 12));


	}

	//BiPredicate中的boolean test(T t1, T t2);
	//String中的boolean t1.equals(t2)
	@Test
	public void test6() {
		BiPredicate<String ,String> pre= new BiPredicate<String, String>() {
			@Override
			public boolean test(String s, String s2) {
				return s.equals(s2);
			}
		};

		BiPredicate<String ,String> pre1 = (s1,s2) ->s1.equals(s2);
		System.out.println(pre1.test("lijin", "lijin"));

		BiPredicate<String ,String> pre2 = String :: equals;
		System.out.println(pre2.test("sfs", "sfsw"));
	}
	
	// Function中的R apply(T t)
	// Employee中的String getName();
	@Test
	public void test7() {
		Employee emp = new Employee(1001, "ksg", 23, 444444);

		Function<Employee,String> func = new Function<Employee, String>() {
			@Override
			public String apply(Employee employee) {
				return employee.getName();
			}
		};

		Function<Employee,String> func1 = e -> e.getName();
		System.out.println(func1.apply(emp));

		Function<Employee,String> func2 = Employee::getName;
		System.out.println(func2.apply(emp));

	}

}
